"""
白名单服务层
"""
from typing import List, Optional, Dict, Any
from datetime import datetime

from src.models.whitelist import (
    WhitelistEntry,
    WhitelistType,
    WhitelistStatus,
    WhitelistMatchResult,
    WhitelistFilter,
    WhitelistStatistics,
    WhitelistBatch
)
from src.repositories.whitelist_repository import WhitelistRepository


class WhitelistService:
    """白名单服务"""
    
    def __init__(self, repository: WhitelistRepository):
        """
        初始化白名单服务
        
        Args:
            repository: 白名单仓库
        """
        self.repository = repository
    
    async def add_entry(
        self,
        type: WhitelistType,
        value: str,
        name: str,
        created_by: str,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None
    ) -> str:
        """
        添加白名单条目
        
        Args:
            type: 类型
            value: 值
            name: 名称
            created_by: 创建者
            description: 描述
            tags: 标签
            
        Returns:
            条目ID
        """
        entry = WhitelistEntry(
            type=type,
            value=value,
            name=name,
            created_by=created_by,
            description=description,
            tags=tags or [],
            status=WhitelistStatus.ACTIVE
        )
        
        return await self.repository.create(entry)
    
    async def get_entry(self, entry_id: str) -> Optional[WhitelistEntry]:
        """
        获取白名单条目
        
        Args:
            entry_id: 条目ID
            
        Returns:
            条目
        """
        return await self.repository.get(entry_id)
    
    async def update_entry(
        self,
        entry_id: str,
        name: Optional[str] = None,
        description: Optional[str] = None,
        tags: Optional[List[str]] = None,
        status: Optional[WhitelistStatus] = None
    ) -> bool:
        """
        更新白名单条目
        
        Args:
            entry_id: 条目ID
            name: 名称
            description: 描述
            tags: 标签
            status: 状态
            
        Returns:
            是否成功
        """
        updates = {}
        if name is not None:
            updates['name'] = name
        if description is not None:
            updates['description'] = description
        if tags is not None:
            updates['tags'] = tags
        if status is not None:
            updates['status'] = status
        
        if not updates:
            return False
        
        return await self.repository.update(entry_id, updates)
    
    async def delete_entry(self, entry_id: str) -> bool:
        """
        删除白名单条目
        
        Args:
            entry_id: 条目ID
            
        Returns:
            是否成功
        """
        return await self.repository.delete(entry_id)
    
    async def list_entries(
        self,
        type: Optional[WhitelistType] = None,
        status: Optional[WhitelistStatus] = None,
        tags: Optional[List[str]] = None,
        created_by: Optional[str] = None,
        search_text: Optional[str] = None,
        page: int = 1,
        page_size: int = 20
    ) -> List[WhitelistEntry]:
        """
        列出白名单条目
        
        Args:
            type: 类型过滤
            status: 状态过滤
            tags: 标签过滤
            created_by: 创建者过滤
            search_text: 搜索文本
            page: 页码
            page_size: 页大小
            
        Returns:
            条目列表
        """
        filter = WhitelistFilter(
            type=type,
            status=status,
            tags=tags,
            created_by=created_by,
            search_text=search_text,
            page=page,
            page_size=page_size
        )
        
        return await self.repository.list(filter)
    
    async def check_whitelist(
        self,
        content: str,
        check_type: Optional[WhitelistType] = None
    ) -> WhitelistMatchResult:
        """
        检查内容是否在白名单中
        
        Args:
            content: 内容
            check_type: 检查类型
            
        Returns:
            匹配结果
        """
        return await self.repository.match(content, check_type)
    
    async def batch_add(
        self,
        entries_data: List[Dict[str, Any]],
        created_by: str
    ) -> List[str]:
        """
        批量添加白名单
        
        Args:
            entries_data: 条目数据列表
            created_by: 创建者
            
        Returns:
            创建的ID列表
        """
        entries = []
        for data in entries_data:
            entry = WhitelistEntry(
                type=data.get('type', WhitelistType.DOMAIN),
                value=data['value'],
                name=data['name'],
                created_by=created_by,
                description=data.get('description'),
                tags=data.get('tags', []),
                status=WhitelistStatus.ACTIVE
            )
            entries.append(entry)
        
        return await self.repository.batch_create(entries)
    
    async def batch_delete(self, entry_ids: List[str]) -> int:
        """
        批量删除白名单
        
        Args:
            entry_ids: ID列表
            
        Returns:
            删除数量
        """
        return await self.repository.batch_delete(entry_ids)
    
    async def activate_entry(self, entry_id: str) -> bool:
        """
        激活白名单条目
        
        Args:
            entry_id: 条目ID
            
        Returns:
            是否成功
        """
        return await self.repository.update_status(entry_id, WhitelistStatus.ACTIVE)
    
    async def deactivate_entry(self, entry_id: str) -> bool:
        """
        停用白名单条目
        
        Args:
            entry_id: 条目ID
            
        Returns:
            是否成功
        """
        return await self.repository.update_status(entry_id, WhitelistStatus.INACTIVE)
    
    async def get_statistics(self) -> WhitelistStatistics:
        """
        获取统计信息
        
        Returns:
            统计信息
        """
        return await self.repository.get_statistics()
    
    async def import_from_file(
        self,
        file_path: str,
        file_type: str,
        created_by: str
    ) -> Dict[str, Any]:
        """
        从文件导入白名单
        
        Args:
            file_path: 文件路径
            file_type: 文件类型 (csv, json, txt)
            created_by: 创建者
            
        Returns:
            导入结果
        """
        import json
        import csv
        
        entries_data = []
        
        if file_type == 'json':
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                if isinstance(data, list):
                    entries_data = data
                elif isinstance(data, dict) and 'entries' in data:
                    entries_data = data['entries']
        
        elif file_type == 'csv':
            with open(file_path, 'r', encoding='utf-8') as f:
                reader = csv.DictReader(f)
                entries_data = list(reader)
        
        elif file_type == 'txt':
            with open(file_path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if line:
                        entries_data.append({
                            'value': line,
                            'name': line,
                            'type': self._detect_type(line)
                        })
        
        # 批量添加
        if entries_data:
            ids = await self.batch_add(entries_data, created_by)
            return {
                'success': True,
                'imported_count': len(ids),
                'ids': ids
            }
        
        return {
            'success': False,
            'error': 'No valid entries found in file'
        }
    
    async def export_to_file(
        self,
        file_path: str,
        file_type: str,
        filter: Optional[WhitelistFilter] = None
    ) -> bool:
        """
        导出白名单到文件
        
        Args:
            file_path: 文件路径
            file_type: 文件类型 (csv, json, txt)
            filter: 过滤条件
            
        Returns:
            是否成功
        """
        import json
        import csv
        
        # 获取所有符合条件的条目
        if not filter:
            filter = WhitelistFilter(page_size=10000)  # 最多导出10000条
        
        entries = await self.repository.list(filter)
        
        if file_type == 'json':
            with open(file_path, 'w', encoding='utf-8') as f:
                data = [entry.model_dump() for entry in entries]
                json.dump(data, f, ensure_ascii=False, indent=2, default=str)
        
        elif file_type == 'csv':
            with open(file_path, 'w', encoding='utf-8', newline='') as f:
                if entries:
                    fieldnames = ['id', 'type', 'value', 'name', 'description', 
                                 'status', 'created_by', 'created_at', 'tags']
                    writer = csv.DictWriter(f, fieldnames=fieldnames)
                    writer.writeheader()
                    for entry in entries:
                        row = entry.model_dump()
                        row['tags'] = ','.join(row.get('tags', []))
                        row['created_at'] = str(row.get('created_at', ''))
                        writer.writerow(row)
        
        elif file_type == 'txt':
            with open(file_path, 'w', encoding='utf-8') as f:
                for entry in entries:
                    f.write(f"{entry.value}\n")
        
        return True
    
    def _detect_type(self, value: str) -> WhitelistType:
        """
        自动检测值的类型
        
        Args:
            value: 值
            
        Returns:
            类型
        """
        # 简单的类型检测逻辑
        if value.startswith('http://') or value.startswith('https://'):
            return WhitelistType.URL
        elif '.' in value and not ' ' in value:
            # 可能是域名
            parts = value.split('.')
            if len(parts) >= 2 and all(part.isalnum() or '-' in part for part in parts):
                return WhitelistType.DOMAIN
        elif value.startswith('^') or value.endswith('$') or '*' in value:
            return WhitelistType.PATTERN
        
        return WhitelistType.SOURCE
    
    async def ensure_indexes(self):
        """确保索引创建"""
        await self.repository.ensure_indexes()